part of _;

extension on ChatView {
  Widget message_list(MessageModel message) {
    if (message.isRevoke) {
      return Container(
        padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
        alignment: Alignment.center,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("${message.isMine ? "您" : "对方"}撤回了一条消息", style: TextStyle(color: Colors.grey, fontSize: 12)),
            message.isMine && message.messageType == Enum_MessageType.Text
                ? YButton(
                    isInk: true,
                    margin: EdgeInsets.only(left: 5),
                    child: Text("重新编辑", style: TextStyle(color: YConfig.themeColor, fontSize: 12)),
                    onTap: () {
                      page.controller_chat!.state.textEditingController.text = "${page.controller_chat!.state.textEditingController.text}${message.content}";
                      page.controller_chat!.state.focusNode.requestFocus();
                    },
                  )
                : YEmpty(),
          ],
        ),
      );
    }

    Widget message_common_left({required Widget child, required EdgeInsetsGeometry padding, bool isShowUnPlayed = false}) {
      return Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          YImageCorner(30, 30, message.avatar, 5),
          YSpacer(width: 10),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    GestureDetector(
                      child: Container(
                        padding: padding,
                        constraints: BoxConstraints(maxWidth: yScreenSize().width - 500, minHeight: 30),
                        decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)),
                        child: child,
                      ),
                      onTap: () => doMessageTap(message),
                      onSecondaryTapDown: (details) => doMessageSecondaryTap(details, message),
                    ),
                    isShowUnPlayed
                        ? Container(
                            width: 7,
                            height: 7,
                            margin: EdgeInsets.only(left: 10),
                            decoration: BoxDecoration(color: YConfig.themeColor, borderRadius: BorderRadius.circular(99)),
                          )
                        : YEmpty(),
                  ],
                ),
              ],
            ),
          ),
          YSpacer(width: 50),
        ],
      );
    }

    Widget message_common_right({required Widget child, required EdgeInsetsGeometry padding}) {
      Widget send_messageState() {
        final size = 15.0;
        switch (message.messageState) {
          case YIMEnum_MessageState.Sending:
            return Container(
              width: size + 20,
              height: size + 20,
              padding: EdgeInsets.all(10),
              child: CircularProgressIndicator(strokeWidth: 2),
            );
          case YIMEnum_MessageState.Success_Read:
            return Container(
              padding: EdgeInsets.all(10),
              child: Icon(Icons.check_circle, color: YConfig.themeColor, size: size),
            );
          case YIMEnum_MessageState.Success_UnRead:
            return Container(
              padding: EdgeInsets.all(10),
              child: Icon(Icons.check_circle_outline, color: YConfig.themeColor, size: size),
            );
          case YIMEnum_MessageState.Fail:
            return YButton(
              width: size + 20,
              height: size + 20,
              borderRadius: BorderRadius.circular(99),
              child: Container(
                padding: EdgeInsets.all(10),
                child: Icon(Icons.cancel_schedule_send_rounded, color: Colors.red, size: size),
              ),
              onTap: () {
                yShowBuilder("重新发送？", () {
                  YIM.messageManager.deleteLocalMessage(conversationType: YIMEnum_ConversationType.P2P, conversationID: page.controller_conversation!.getSelectConversation()!.conversationID, messageID: message.id);
                  page.controller_chat!.state.messages.remove(page.controller_chat!.state.messages.lastWhere((element) => element.id == message.id));

                  void reSendMessage() {
                    page.controller_chat!.sendMessage(
                      message.messageType,
                      message.content,
                      onSendStart: (yimMessage) {
                        page.controller_chat!.addMessages(messages: [MessageModel.fromYIMMessage(yimMessage, true)..progress_upload = 100]);
                        page.controller_chat!.scrollToBottom();
                      },
                    );
                  }

                  void reUploadMessage() {
                    page.controller_chat!.addUploadMessages([message.content], message.messageType);
                  }

                  switch (message.messageType) {
                    case Enum_MessageType.Text:
                      reSendMessage();
                      break;
                    case Enum_MessageType.Voice:
                    case Enum_MessageType.Image:
                    case Enum_MessageType.Video:
                      if (message.progress_upload == -1) {
                        reUploadMessage();
                      } else {
                        reSendMessage();
                      }
                      break;
                    default:
                      break;
                  }
                }, null, true);
              },
            );
          case YIMEnum_MessageState.UnKnown:
            return Container(
              padding: EdgeInsets.all(10),
              child: Icon(Icons.error, color: Colors.red, size: size),
            );
        }
      }

      return Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          YSpacer(width: 50),
          Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  send_messageState(),
                  GestureDetector(
                    child: Container(
                      padding: padding,
                      constraints: BoxConstraints(maxWidth: yScreenSize().width - 500, minHeight: 30),
                      decoration: BoxDecoration(color: YConfig.themeColor.withAlpha(30), borderRadius: BorderRadius.circular(5)),
                      child: child,
                    ),
                    onTap: () => doMessageTap(message),
                    onSecondaryTapDown: (details) => doMessageSecondaryTap(details, message),
                  ),
                ],
              ),
            ],
          ),
          YSpacer(width: 10),
          YImageCorner(30, 30, message.avatar, 5),
        ],
      );
    }

    Widget progress({Widget? finishWidget}) {
      return message.messageState == YIMEnum_MessageState.Sending
          ? message.progress_upload <= 0
              ? CircularProgressIndicator(color: Colors.white)
              : message.progress_upload < 100
                  ? CircularProgressIndicator(color: Colors.white, value: message.progress_upload / 100.0)
                  : finishWidget ?? YEmpty()
          : finishWidget ?? YEmpty();
    }

    switch (message.messageType) {
      case Enum_MessageType.Text:
        final messageWidget = ExtendedSelectableText(
          message.content.fixAutoLines(),
          specialTextSpanBuilder: mySpecialTextSpanBuilder,
          style: TextStyle(color: Colors.black, fontSize: 12),
        );
        return !message.isMine
            ? message_common_left(
                padding: EdgeInsets.fromLTRB(10, 8, 10, 8),
                child: messageWidget,
              )
            : message_common_right(
                padding: EdgeInsets.fromLTRB(10, 8, 10, 8),
                child: messageWidget,
              );
      case Enum_MessageType.Voice:
        Map<String, dynamic> content = json.decode(message.content);
        int second = content["second"];
        String url = content["url"];
        return !message.isMine
            ? message_common_left(
                padding: EdgeInsets.fromLTRB(0, 3, 30 + second * 1, 3),
                isShowUnPlayed: !message.isVoicePlayed,
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    ChatRecordMsg(url: url, direction: ChatRecordMsgDirection.Left, isPlay: message.isVoicePlaying),
                    YSpacer(width: 10),
                    Text("$second\"", style: TextStyle(fontSize: 12)),
                  ],
                ),
              )
            : message_common_right(
                padding: EdgeInsets.fromLTRB(30 + second * 1, 3, 0, 3),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text("$second\"", style: TextStyle(fontSize: 12)),
                    YSpacer(width: 10),
                    ChatRecordMsg(url: url, direction: ChatRecordMsgDirection.Right, isPlay: message.isVoicePlaying),
                  ],
                ),
              );
      case Enum_MessageType.Image:
        final messageWidget = Container(
          constraints: BoxConstraints(maxHeight: 300),
          child: Stack(
            alignment: Alignment.center,
            children: [
              message.content.startsWith("http")
                  ? YImageCorner(150, null, message.content, 5)
                  : ClipRRect(
                      borderRadius: BorderRadius.circular(5),
                      child: Image.file(File(message.content), width: 150),
                    ),
              progress(),
            ],
          ),
        );
        return !message.isMine
            ? message_common_left(
                padding: EdgeInsets.all(5),
                child: messageWidget,
              )
            : message_common_right(
                padding: EdgeInsets.all(5),
                child: messageWidget,
              );
      case Enum_MessageType.Video:
        final messageWidget = Container(
          constraints: BoxConstraints(maxHeight: 300),
          child: Stack(
            alignment: Alignment.center,
            children: [
              message.content.startsWith("http")
                  ? YImageCorner(150, null, YOSS.ossVideo2Image(message.content), 5)
                  : ClipRRect(
                      borderRadius: BorderRadius.circular(5),
                      child: message.videoThumbnailPath.isEmpty
                          ? Container(
                              width: 150,
                              height: 150,
                              child: YCircularProgress(size: 30),
                            )
                          : Image.file(
                              File(message.videoThumbnailPath),
                              width: 150,
                            ),
                    ),
              progress(finishWidget: Icon(Icons.play_circle_outline_rounded, color: Colors.white, size: 40)),
            ],
          ),
        );
        return !message.isMine
            ? message_common_left(
                padding: EdgeInsets.all(5),
                child: messageWidget,
              )
            : message_common_right(
                padding: EdgeInsets.all(5),
                child: messageWidget,
              );
      default:
        return YEmpty();
    }
  }
}
